﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Vds2465Telegrams
{
    public enum eTelegramFunction_Calling
    {
        SEND_NORM,
		SEND_NDAT,
        REQ_STATUS,
        REQ_NDAT
    }

	public class Telegram_Calling : Telegram
    {
		#region private member variables

		private readonly eTelegramFunction_Calling _telegramFunction;
		private readonly bool _frameCountFlag;						// true = 1, false = 0, change/toggle between calls
		private readonly bool _frameCountValid;	

		#endregion private member variables

		#region constructor

		public Telegram_Calling(eDirection direction, byte address, eTelegramFunction_Calling telegramFunctionCalling, bool frameCountValid, bool frameCountFlag) 
			: base (direction, address)
		{
			_telegramFunction = telegramFunctionCalling;
			_frameCountValid = frameCountValid;
			_frameCountFlag = frameCountFlag;			
		}

		#endregion constructor

		#region public getters

		public eTelegramFunction_Calling TelegramFunction { get { return _telegramFunction; } }

		/// <summary>
		/// true = 1, false = 0, change/toggle between calls,
		/// used to differentiate messages (with the same data) that are sent more than once
		/// in e.g. transmission error scenarios
		/// </summary>
		public bool FrameCountFlag { get { return _frameCountFlag; } }

		/// <summary>
		/// set to true to signalize that the FrameCountFlag is valid, i.e. frame counting is active/valid
		/// </summary>
		public bool FrameCountValid { get { return _frameCountValid; } }

		#endregion public getters

		#region ToString, Equals, GetHashCode

		public override int GetHashCode()
        {
            int hashCode = base.GetHashCode();
            if (FrameCountFlag)
            {
                hashCode ^= 0x01; 
            }
            if (FrameCountValid)
            {
                hashCode ^= 0x02; 
            }
            switch (TelegramFunction)
            {
                case eTelegramFunction_Calling.SEND_NORM:
                    hashCode ^= 0x04;
                    break;
                case eTelegramFunction_Calling.SEND_NDAT:
                    hashCode ^= 0x08;
                    break;
                case eTelegramFunction_Calling.REQ_STATUS:
                    hashCode ^= 0x10;
                    break;
                case eTelegramFunction_Calling.REQ_NDAT:
                    hashCode ^= 0x20;
                    break;
                default:
					// TODO handle error
                    hashCode ^= 0x40;
                    break;
            }

            return hashCode;
        }

        public override string ToString()
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("(");
            stringBuilder.Append(ToStringProperties());
            stringBuilder.Append(")");

            return stringBuilder.ToString();
        }

        internal override string ToStringProperties()
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(base.ToStringProperties());
            stringBuilder.Append(", ");

            stringBuilder.Append("TelegramFunction=");
            switch (TelegramFunction)
            {
                case eTelegramFunction_Calling.SEND_NORM:
                    stringBuilder.Append("SEND_NORM");
                    break;
                case eTelegramFunction_Calling.SEND_NDAT:
                    stringBuilder.Append("SEND_NDAT");
                    break;
                case eTelegramFunction_Calling.REQ_STATUS:
                    stringBuilder.Append("REQ_STATUS");
                    break;
                case eTelegramFunction_Calling.REQ_NDAT:
                    stringBuilder.Append("REQ_NDAT");
                    break;
                default:
					// TODO handle error
                    stringBuilder.Append("UNKNOWN");
                    break;
            }

            stringBuilder.Append("', ");
            stringBuilder.Append("FrameCountFlag='");
            stringBuilder.Append(FrameCountFlag ? "true" : "false");
            stringBuilder.Append("'");

            stringBuilder.Append("', ");
            stringBuilder.Append("FrameCountValid='");
            stringBuilder.Append(FrameCountValid ? "true" : "false");
            stringBuilder.Append("'");
            return stringBuilder.ToString();
        }

        public override bool Equals(object obj)
        {
            Type objType = obj.GetType();
            if (this.GetType() == objType)
            {
                Telegram_Calling telegramCalling2Compare = obj as Telegram_Calling;
                return EqualsProperties(telegramCalling2Compare);
            }

            return false;
        }

        internal virtual bool EqualsProperties(Telegram_Calling telegramCalling2Compare)
        {
            if (base.EqualsProperties(telegramCalling2Compare))
            {
                if (FrameCountFlag == telegramCalling2Compare.FrameCountFlag)
                {
                    if (FrameCountValid == telegramCalling2Compare.FrameCountValid)
                    {
                        return (TelegramFunction == telegramCalling2Compare.TelegramFunction);
                    }

                    return false;
                }

                return false;
            }

            return false;
		}

		#endregion ToString, Equals, GetHashCode
	}
}
